/*
 * Copyright (c) 2012 SUBSECRETARIA DEFENSORIA DEL ESPACIO PUBLICO - SDEP.
 * All Rights Reserved.
 * This software is the confidential and proprietary information of SDEP
 * Developed By CONSTULT-SOFT S.A, Development Team 2012.
 *
 */
package co.gov.medellin.sdep.sisdep.domain;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;

import co.gov.medellin.sdep.sisdep.cco.exception.LocalException;
import co.gov.medellin.sdep.sisdep.common.AppConstants;
import co.gov.medellin.sdep.sisdep.common.OracleHelper;
import co.gov.medellin.sdep.sisdep.common.enums.UploadFileEnum;
import co.gov.medellin.sdep.sisdep.common.exception.ArchivoAnexoException;
import co.gov.medellin.sdep.sisdep.model.Agenda;
import co.gov.medellin.sdep.sisdep.model.ArchivoAnexo;
import co.gov.medellin.sdep.sisdep.model.ModuloDiseno;
import co.gov.medellin.sdep.sisdep.regulacion.exception.ModuloDisenoException;
import co.gov.medellin.sdep.sisdep.regulacion.exception.ModuloDisenoRuntimeException;
import co.gov.medellin.sdep.sisdep.regulacion.service.IModuloDisenoService;

/**
 * <p>
 * Clase controladora que permite realizar el proceso de configuracion de disenos de Modulos.
 * Permite al usuario realizar operaciones de consulta, creacion y actualizacion de registros.
 * </p>
 * <p>
 * Copyright (c) 2012<BR>
 * Consult-Soft S.A.<BR>
 * Created on: May 09, 2012<BR>
 * 
 * @author atabares
 * </p>
 */
public class ModuloDisenoController extends BaseController implements Serializable {
	
	/** generated serial version. */
	private static final long serialVersionUID = -2779225027393211769L;

	/** Mensaje usado en el mensaje de confirmacion en la actualizacion de disenos de modulos. */
	public static final String SEARCH_RETURN = " Desea regresar a la pantalla de Consulta de Dise\u00F1o de Modulos?";
	
	/** Bean para el manejo del formulario de busqueda ModuloDiseno. */
	private ModuloDiseno moduloDisenoSearch = new ModuloDiseno();

	/** Objeto contenedor del listado de ModuloDiseno luego de una consulta. */
	private transient DataModel moduloDisenoListModel;

	/** Bean para el manejo del formulario de creacion/edicion. */
	private ModuloDiseno moduloDiseno = new ModuloDiseno();

	/** Instancia de servicio moduloDisenoService. */
	private IModuloDisenoService moduloDisenoService;

	
	/**
	 * Constructor por defecto, inicializa los elemento basicos del Controlador
	 */
	public ModuloDisenoController() {
		this.moduloDisenoListModel = new ListDataModel();
	}

	/**
	 * Obtiene el parametro moduloDisenoSearch.
	 * @see ModuloDisenoController#moduloDisenoSearch
	 *
	 * @return El parametro moduloDisenoSearch.
	 */
	public ModuloDiseno getModuloDisenoSearch() {
		return moduloDisenoSearch;
	}

	/**
	 * Asigna el parametro moduloDisenoSearch.
	 * @see ModuloDisenoController#moduloDisenoSearch
	 *
	 * @param moduloDisenoSearch valor a asignar al parametro moduloDisenoSearch.
	 */
	public void setModuloDisenoSearch(ModuloDiseno moduloDisenoSearch) {
		this.moduloDisenoSearch = moduloDisenoSearch;
	}

	/**
	 * Obtiene el parametro moduloDisenoListModel.
	 * @see ModuloDisenoController#moduloDisenoListModel
	 *
	 * @return El parametro moduloDisenoListModel.
	 */
	public DataModel getModuloDisenoListModel() {
		return moduloDisenoListModel;
	}

	/**
	 * Asigna el parametro moduloDisenoListModel.
	 * @see ModuloDisenoController#moduloDisenoListModel
	 *
	 * @param moduloDisenoListModel valor a asignar al parametro moduloDisenoListModel.
	 */
	public void setModuloDisenoListModel(DataModel moduloDisenoListModel) {
		this.moduloDisenoListModel = moduloDisenoListModel;
	}

	/**
	 * Obtiene el parametro moduloDiseno.
	 * @see ModuloDisenoController#moduloDiseno
	 *
	 * @return El parametro moduloDiseno.
	 */
	public ModuloDiseno getModuloDiseno() {
		return moduloDiseno;
	}

	/**
	 * Asigna el parametro moduloDiseno.
	 * @see ModuloDisenoController#moduloDiseno
	 *
	 * @param moduloDiseno valor a asignar al parametro moduloDiseno.
	 */
	public void setModuloDiseno(ModuloDiseno moduloDiseno) {
		this.moduloDiseno = moduloDiseno;
	}

	/**
	 * Obtiene el parametro moduloDisenoService.
	 * @see ModuloDisenoController#moduloDisenoService
	 *
	 * @return El parametro moduloDisenoService.
	 */
	public IModuloDisenoService getModuloDisenoService() {
		return moduloDisenoService;
	}

	/**
	 * Asigna el parametro moduloDisenoService.
	 * @see ModuloDisenoController#moduloDisenoService
	 *
	 * @param moduloDisenoService valor a asignar al parametro moduloDisenoService.
	 */
	public void setModuloDisenoService(IModuloDisenoService moduloDisenoService) {
		this.moduloDisenoService = moduloDisenoService;
	}

	
	/**
	 * Obtiene los registros de los disenios de los modulos que coinciden con los parametros de busqueda ingresados.
	 * @return La cadena que redirecciona a la pagina de resultados de busqueda de disenios de modulos.
	 */
	public String getModuloDisenoListByParameters() {
		try {
			List moduloDisenoList = getModuloDisenoService().getModuloDisenoListByCriteria(this.moduloDisenoSearch);			
			this.moduloDisenoListModel.setWrappedData(moduloDisenoList);
			
		} catch (Exception e) {
			e.printStackTrace(System.err);
			
			((MessageModalWindowController) getBean(AppConstants.MESSAGE_CONTROLLER_BEAN))
				.setErrorMessage(AppConstants.DEFAULT_ERROR + e.getMessage(), null, null);
		}
		
		if (this.moduloDisenoListModel.getWrappedData() == null 
				|| ((List) this.moduloDisenoListModel.getWrappedData()).isEmpty()) {
			
			((MessageModalWindowController) getBean(AppConstants.MESSAGE_CONTROLLER_BEAN))
				.setAlertMessage(AppConstants.NO_RECORDS_FOUND, null, null);
		}
		
		return AppConstants.MODULO_DISENO_SEARCH_VIEW;
	}
	
	/**
	 * Ajusta las propiedades de disenios de Modulos e invoca los metodos necesarios para su insercion en DB.
	 * @return La cadena que redirecciona a la pagina de creacion de disenios de modulos.
	 */
	public String create() {
		this.moduloDiseno.setUsuarioCrea(BaseController.getLoggedUserID());
		
		ArchivoAnexo archivoAnexoUploaded = (ArchivoAnexo) UploadFileController.getSessionObject(AppConstants.SESSION_UPLOADED_FILE);
		
		if (archivoAnexoUploaded != null) {
			this.moduloDiseno.setIdFotoAnexoDiseno(archivoAnexoUploaded.getId().toString());
			this.moduloDiseno.setFotoAnexoDiseno(archivoAnexoUploaded.getNombreInterno());
		}
		
		try {
			getModuloDisenoService().insert(this.moduloDiseno);
			
			((MessageModalWindowController) getBean(AppConstants.MESSAGE_CONTROLLER_BEAN))
				.setSuccessMessage(AppConstants.SUCCESS_CREATE, null, null);
			
			this.moduloDiseno = new ModuloDiseno();
		} catch (ModuloDisenoException e) {
			e.printStackTrace(System.err);
			
			((MessageModalWindowController) getBean(AppConstants.MESSAGE_CONTROLLER_BEAN))
				.setErrorMessage(AppConstants.DEFAULT_ERROR + e.getEndUserMessage(), null, null);
		} catch (ModuloDisenoRuntimeException e) {
			e.printStackTrace(System.err);
			
			((MessageModalWindowController) getBean(AppConstants.MESSAGE_CONTROLLER_BEAN))
				.setErrorMessage(AppConstants.DEFAULT_ERROR + e.getEndUserMessage(), null, null);
		}
		
		return AppConstants.MODULO_DISENO_CREATE_VIEW;
	}

	
	/**
	 * 
	 */
	public String createModuloDiseno() {
		moduloDiseno = new ModuloDiseno();
		moduloDiseno.setId(null);
		moduloDiseno.setUsuarioCrea(getLoggedUserID());
		moduloDiseno.setUsuarioModifica(getLoggedUserID());
		return AppConstants.MODULO_DISENO_CREATE_VIEW;
	}
	
	/**
	 * Obtiene el disenio del modulo seleccionado desde base de datos para permitir su actualizacion.
	 * @return La cadena que redirecciona a la pagina de actualizacion de disenios de modulos.
	 */
	public String updateModuloDiseno() {
		Map params = getExternalContext().getRequestParameterMap();
		String moduloDisenoDataIndex = (String) params.get("moduloDisenoDataIndex");
		List moduloDisenoListTemp = (List) this.moduloDisenoListModel.getWrappedData();

		Long idModuloDiseno = ((ModuloDiseno) moduloDisenoListTemp.get(Integer.parseInt(moduloDisenoDataIndex))).getId();		
		try {
			this.moduloDiseno = getModuloDisenoService().get(idModuloDiseno.longValue());
			this.moduloDiseno.setActualizacion(true);
		} catch (ModuloDisenoException e) {
			e.printStackTrace(System.err);
			
			((MessageModalWindowController) getBean(AppConstants.MESSAGE_CONTROLLER_BEAN))
				.setErrorMessage(AppConstants.DEFAULT_ERROR + e.getEndUserMessage(), null, null);
		}		
		return AppConstants.MODULO_DISENO_UPDATE_VIEW;
	}
	
	/**
	 * Ajusta las propiedades de disenios de Modulos e invoca los metodos necesarios para su actualizacion en DB.
	 * @return La cadena que redirecciona a la pagina de actualizacion de disenios de modulos.
	 */
	public String update() {
		this.moduloDiseno.setUsuarioModifica(BaseController.getLoggedUserID());
		
		ArchivoAnexo archivoAnexoUploaded = (ArchivoAnexo) UploadFileController.getSessionObject(AppConstants.SESSION_UPLOADED_FILE);
		
		if (archivoAnexoUploaded != null) {
			this.moduloDiseno.setIdFotoAnexoDiseno(archivoAnexoUploaded.getId().toString());
			this.moduloDiseno.setFotoAnexoDiseno(archivoAnexoUploaded.getNombreInterno());
		}
		
		try {
			if (this.moduloDiseno.getId().longValue() != 0L) {
				getModuloDisenoService().update(this.moduloDiseno);
				
				getModuloDisenoListByParameters();
				
				((MessageModalWindowController) getBean(AppConstants.MESSAGE_CONTROLLER_BEAN))
					.setConfirmMessage(AppConstants.SUCCESS_UPDATE + ModuloDisenoController.SEARCH_RETURN, 
						MessageModalWindowController.ACTION_NAVIGATE, AppConstants.MODULO_DISENO_SEARCH_VIEW, 
							AppConstants.MODULO_DISENO_UPDATE_VIEW);
			}
		} catch (ModuloDisenoException e) {
			e.printStackTrace(System.err);
			
			((MessageModalWindowController) getBean(AppConstants.MESSAGE_CONTROLLER_BEAN))
				.setErrorMessage(AppConstants.DEFAULT_ERROR + e.getEndUserMessage(), null, null);
		} catch (ModuloDisenoRuntimeException e) {
			e.printStackTrace(System.err);
			
			((MessageModalWindowController) getBean(AppConstants.MESSAGE_CONTROLLER_BEAN))
				.setErrorMessage(AppConstants.DEFAULT_ERROR + e.getEndUserMessage(), null, null);
		}
		
		return AppConstants.MODULO_DISENO_UPDATE_VIEW;
	}
	
	/**
	 * Configura y sube en sesion los parametros necesarios para que el componente de carga de archivos 
	 * inicie su proceso.
	 * @return La cadena que redirecciona a la pagina de creacion/actualizacion de disenios de modulos.
	 */
	public String loadModuloDisenoPhoto() {
		ArchivoAnexo archivoAnexoSession = new ArchivoAnexo();
		archivoAnexoSession.setTipoAnexo(UploadFileEnum.REGULACION);
		archivoAnexoSession.setTipoFuente(UploadFileEnum.REGULACION);
		archivoAnexoSession.setIdFuente(this.moduloDiseno.getId());
		archivoAnexoSession.setActualizacion(this.moduloDiseno.isActualizacion());
		
		// TODO: esto debe ser eliminado las tablas no deben almacenar IDs de anexos: 23-07-2012
		if (!OracleHelper.isNullorEmpty(this.moduloDiseno.getIdFotoAnexoDiseno())) {
			archivoAnexoSession.setId(new Long(this.moduloDiseno.getIdFotoAnexoDiseno()));
		}
		
		this.setSessionObject(AppConstants.SESSION_PENDING_FILE, archivoAnexoSession);
		
		return AppConstants.MODULO_DISENO_CREATE_VIEW;
	}
	
	/**
	 * Elimina del servidor el archivo anexo asociado.
	 * @return La cadena que redirecciona a la pagina de creacion/actualizacion de disenios de modulos.
	 * @throws ArchivoAnexoException 
	 */
	public String deleteModuloDisenoPhoto() throws ArchivoAnexoException {
		ArchivoAnexo archivoAnexo = new ArchivoAnexo();
		archivoAnexo.setId(new Long(this.moduloDiseno.getIdFotoAnexoDiseno()));
		
		if (!OracleHelper.isNullorEmpty(this.moduloDiseno.getIdFotoAnexoDiseno())) {
			//PENDIENTE ACTUALIZAR EL CAMPO IDFOTOANEXODISENO.
			UploadFileController.getInstance().deleteFile(archivoAnexo);
		}
		
		return AppConstants.MODULO_DISENO_CREATE_VIEW;
	}

	/**
	 * Metodo que permite cancelar una operacion de Crear / Actualizar un Disenio de Modulo 
	 * @author carlos.perez@consult-soft.com  26-07-2012
	 * @return String
	 */
	public String cancelModuloDiseno() {
		return AppConstants.MODULO_DISENO_SEARCH_VIEW;
	}

}
